#include <rtthread.h>


#ifdef RT_USING_FINSH
#include <finsh.h>
#endif

#include "gagent_def.h"
//

static con_st con;        //config info
cloud_st *cloud = RT_NULL;     //cloud handle
lan_st *lan = RT_NULL;       //lan handle

int gagent_recv_packet(rt_uint8_t from, rt_uint8_t action, rt_uint8_t *kv, rt_uint16_t kv_len)
{
    rt_kprintf("from:%s\n", (from == CMD_FROM_LAN) ? "lan packet" : "mqtt packet");

//    switch(action)
//    {
//        case : 
//        break;
//    }
    
    return RT_EOK;
}

int gagent_send_packet(rt_uint8_t *kv, rt_uint16_t kv_len)
{

    return RT_EOK;
}

static int gagent_cloud_parse_config(con_st *con, const char *pk, const char *pk_secret)
{
    RT_ASSERT(con != RT_NULL);

    rt_memset(con, 0, sizeof(con_st));
    //
    uint8_t mac_addr[32];
    uint8_t i;
    rt_memset(mac_addr, 0, sizeof(mac_addr));
//    wifi_get_macaddr(STATION_IF, mac_addr);
    rt_memcpy(mac_addr, "\xBC\x12\x34\x56\x78\x23", 6);
    
    for(i = 0; i < 16; i ++)
        rt_kprintf("0x%02x ", mac_addr[i]);
    rt_kprintf("\r\n");
    
    rt_sprintf(con->mac, "%02X-%02X-%02X-%02X-%02X-%02X", \
        mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
    strcpy(con->pk, pk);
    strcpy(con->pk_secret, pk_secret);
    strcpy(con->hard_version, HARD_VERSION);
    strcpy(con->soft_version, SOFT_VERSION);
    strcpy(con->passcode, "e4a8588146");

    rt_kprintf("mac:%s\n", con->mac);
    rt_kprintf("did:%s\n", con->did);
    rt_kprintf("passcode:%s\n", con->passcode);
    rt_kprintf("pk:%s\n", con->pk);
    rt_kprintf("pk_secret:%s\n", con->pk_secret);
    rt_kprintf("hard_version:%s\n", con->hard_version);
    rt_kprintf("soft_version:%s\n", con->soft_version);
    
    return RT_EOK;
}


int gagent_cloud_init(char *mac)
{
    rt_bool_t write_flag = RT_FALSE;
    int rc = RT_EOK;
    
    if(cloud->con->passcode[0] == 0)
    {
        //passcode is empty
        rt_memset(cloud->con->passcode, 0, sizeof(cloud->con->passcode));
        rt_memcpy(cloud->con->passcode, cloud->con->pk, 10);
        write_flag = RT_TRUE;
    }

    if(mac != RT_NULL && mac[0] != 0 && (cloud->con->mac[0] == 0 || strcmp(cloud->con->mac, mac)))
    {
        //mac changed,will register new one;
        rt_memset(cloud->con->did, 0, sizeof(cloud->con->did));
        rt_memset(cloud->con->mac, 0, sizeof(cloud->con->mac));
        rt_memcpy(cloud->con->mac, mac, strlen(mac) > 32 ? 32 : strlen(mac));
        write_flag = RT_TRUE;
    }

    if(cloud->con->did[0] == 0)
    {
        write_flag = RT_TRUE;
        rt_memset(cloud->con->did, 0, sizeof(cloud->con->did));

        rc = gagent_cloud_register();
        if(rc != RT_EOK)
            return rc;
    }

    rc = gagent_cloud_provision();
    if(rc != RT_EOK)
        return rc;
    
    if(RT_TRUE == write_flag)
    {

    }

    return RT_EOK;
}

void gagent_cloud_thread(void *parameter)
{
    int rc = RT_EOK;
    
    rc = gagent_cloud_init(NULL);
    if(cloud == RT_NULL)
    {
        rt_kprintf("gagent_cloud_init failed!\n");
        goto __exit;
    }
    
    rc = gagent_mqtt_init(cloud);
    if(rc != RT_EOK)
    {
        rt_kprintf("gagent_cloud_mqtt_init_failed!\n");
        goto __exit;
    }

    rc = gagent_lan_init(lan);
    if(rc != RT_EOK)
    {
        rt_kprintf("gagent_cloud_lan_init failed!\n");
        goto __exit;
    }

__exit:
    return;
}

int gagent_cloud_stop(void)
{

    return 0;
}


int gagent_cloud_start(const char *product_key, const char *product_secret)
{
    int rc = RT_EOK;
    rt_thread_t thread = RT_NULL;
    
    RT_ASSERT(product_key != RT_NULL);
    RT_ASSERT(product_secret != RT_NULL);

    cloud = RT_NULL;
    lan = RT_NULL;
    
    rc = gagent_cloud_parse_config(&con, product_key, product_secret);
    if(rc != RT_EOK)
    {
        rt_kprintf("gagent_cloud_parse_config failed!\n");
        goto __exit;
    }

    cloud = (cloud_st *)rt_malloc(sizeof(cloud_st));
    if(RT_NULL == cloud)
    {
        rt_kprintf("malloc failed!\n");
        rc = -RT_ENOMEM;
        goto __exit;
    }
    rt_memset(cloud, 0, sizeof(cloud_st));

    lan = (lan_st *)rt_malloc(sizeof(lan_st));
    if(lan == RT_NULL)
    {
        rt_kprintf("malloc failed!\n");
        rc = -RT_ENOMEM;
        goto __exit;
    }
    
    cloud->con = &con;
    lan->con = &con;

    thread = rt_thread_create("gagent", 
                                gagent_cloud_thread, 
                                RT_NULL, 
                                4096, 
                                RT_THREAD_PRIORITY_MAX / 3, 
                                20);
    if(RT_NULL != thread)
    {
        rt_thread_startup(thread);
    }
    else
    {
        rc = -RT_ERROR;
        goto __exit;
    }
    
    return rc;
__exit:
    if(lan != RT_NULL)
        rt_free(lan);

    if(cloud != RT_NULL)
        rt_free(cloud);


    return rc;    
}

int gagent_cloud(void)
{
    int rc = RT_EOK;
    gagent_cloud_start("a567f3304a04456da431e30bae14761a", "f6c8ce3da5b846edac5caa19499b36f1");
    
    return rc;
}
MSH_CMD_EXPORT(gagent_cloud, gagent_cloud);
